package com.dlxj.util.excel;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.util.Region;

public class ExportExcel {

	private List exportList;

	private HashMap<String, String> map;

	private String sheetTitle;

	private List<String[]> footContent;

	private boolean insertRow;

	public ExportExcel(ExportExcelBean exportExcelBean) throws Exception {

		this.exportList = exportExcelBean.getDataSource();

		this.insertRow = exportExcelBean.isInsertRow();

		if (exportList == null && exportExcelBean.getFootContent() == null) {

			throw new Exception("dataSource is null");
		} else {

			this.map = exportExcelBean.getProperties();

			if (map == null || map.size() == 0) {

				throw new Exception("properties is null");

			}

			this.sheetTitle = exportExcelBean.getTitle();
			this.footContent = exportExcelBean.getFootContent();
		}
	}

	public void export(String filePath) throws IntrospectionException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, ClassNotFoundException {

		HashMap<String, String> realMap = new HashMap<String, String>();

		HSSFWorkbook hssfWorkbook = new HSSFWorkbook();

		HSSFSheet hssfSheet = hssfWorkbook.createSheet("Sheet1");

		Collection<String> collections = map.keySet();

		HSSFRow title = hssfSheet.createRow(1);

		short rowIndex = 2;

		int widths[] = new int[map.size()];

		for (int i = 0; i < widths.length; i++) {

			widths[i] = 0;
		}
		HSSFFont font = hssfWorkbook.createFont();

		HSSFCellStyle borderStyle = hssfWorkbook.createCellStyle();

		borderStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
		borderStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		borderStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		borderStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

		if (sheetTitle != null && sheetTitle.length() > 0) {

			hssfSheet.addMergedRegion(new Region(1, (short) 0, 1, (short) (map
					.size() - 1)));
			HSSFCell cell = title.createCell(0);
			HSSFCellStyle hcs = hssfWorkbook.createCellStyle();
			hcs.cloneStyleFrom(borderStyle);
			hcs.setAlignment(CellStyle.ALIGN_CENTER);
			// HSSFFont font = hcs.getFont(hssfWorkbook);
			font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
			font.setFontHeightInPoints((short) 16);
			hcs.setFont(font);
			cell.setCellValue(sheetTitle);
			cell.setCellStyle(hcs);
			for (int i = 1; i < map.size(); i++) {

				HSSFCell tmp = title.createCell(i);
				tmp.setCellStyle(borderStyle);
				tmp.setCellValue("");
			}

			rowIndex++;

			title = hssfSheet.createRow(2);

		}
		font = hssfWorkbook.createFont();
		font.setFontHeightInPoints((short) 14);

		HSSFCellStyle cellStyle = hssfWorkbook.createCellStyle();
		cellStyle.cloneStyleFrom(borderStyle);
		cellStyle.setFont(font);

		short colIndex = 0;
		for (String string : collections) {

			HSSFCell titleCell = title.createCell(colIndex);

			titleCell.setCellValue(string);
			titleCell.setCellStyle(cellStyle);
			int width = string.toString().length();
			width = (width * 13 + 50) / 13 * 300 + 1000;
			widths[colIndex] = width;

			colIndex++;
		}

		font = hssfWorkbook.createFont();

		font.setFontHeightInPoints((short) 12);

		cellStyle = hssfWorkbook.createCellStyle();

		cellStyle.cloneStyleFrom(borderStyle);

		cellStyle.setFont(font);
		if (exportList != null) {
			for (Object object : exportList) {

				HSSFRow hssfRow = hssfSheet.createRow(rowIndex);

				colIndex = 0;

				for (String string : collections) {

					HSSFCell hssfCell = hssfRow.createCell(colIndex);

					String key = map.get(string);

					hssfCell.setCellStyle(cellStyle);
					Object o = null;

					if (key.indexOf(".") == -1) {

						PropertyDescriptor pd = new PropertyDescriptor(key,
								object.getClass());

						Method getMethod = pd.getReadMethod();// ���get����

						o = getMethod.invoke(object);// ִ��get��������һ��Object
					} else {
						String tmpObj = key.substring(0, key.indexOf("."));

						Class<?> c = Class.forName(object.getClass()
								.getPackage().getName()
								+ "."
								+ tmpObj.substring(0, 1).toUpperCase()
								+ tmpObj.substring(1));
						PropertyDescriptor pd = new PropertyDescriptor(tmpObj,
								object.getClass());
						Method method = pd.getReadMethod();
						o = method.invoke(object);
						tmpObj = key.substring(key.indexOf(".") + 1);
						if (o != null) {
							pd = new PropertyDescriptor(tmpObj, o.getClass());
							o = pd.getReadMethod().invoke(o);
						}
					}
					if (o != null) {

						this.setCell(hssfCell, o);
						int width = o.toString().length();
						width = (width * 11 + 50) / 11 * 300 + 1000;
						if (width > widths[colIndex]) {
							widths[colIndex] = width;
						}

					} else {

						hssfCell.setCellValue("");
					}

					colIndex++;
				}
				for (int i = 0; i < widths.length; i++) {
					hssfSheet.setColumnWidth(i, widths[i]);
				}
				rowIndex++;

			}
		}
		if (footContent != null) {
			HSSFFont footFont = hssfWorkbook.createFont();

			footFont.setFontHeightInPoints((short) 12);
			borderStyle.setFont(footFont);
			if (!insertRow) {
				rowIndex--;
			}
			for (String[] strings : footContent) {

				rowIndex++;
				HSSFRow footRow = hssfSheet.createRow(rowIndex);
				int count = 0;
				for (String string : strings) {
					HSSFCell footCell = footRow.createCell(count);

					footCell.setCellStyle(borderStyle);
					footCell.setCellValue(string);
					count++;

				}
			}
		}

		try {

			FileOutputStream fout = new FileOutputStream(filePath);
			hssfWorkbook.write(fout);

			fout.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void setCell(HSSFCell cell, Object obj) {

		if (obj instanceof String) {

			cell.setCellValue(obj.toString());

		} else if (obj instanceof Double) {

			cell.setCellValue(Double.parseDouble(obj.toString()));

		} else if (obj instanceof Date) {

			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

			cell.setCellValue(sdf.format((Date) obj).toString());

		} else if (obj instanceof Integer) {

			cell.setCellValue(Integer.valueOf(obj.toString()));
		}

	}

}
